package com.pioneer.net;

import com.pioneer.util.AppProperties;

import java.net.*;
import java.io.*;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Iterator;
import java.util.ArrayList;

public class Server{
	
	//private Map clients= new HashMap();
	private List clients = new ArrayList();
	private PrintWriter logger;
	
	public Server(int port) {		
		try {
			AppProperties.init();
			String userDir = AppProperties.getProperty(AppProperties.USERDIR);
			String dateStr=new SimpleDateFormat("yyyy_MM_dd_HH_mm").format(new Date());	    
		
			String logPath = userDir+File.separator+"server_log_"+dateStr+".txt";
			
			System.out.println("Logging to "+logPath);	
			logger = new PrintWriter(new FileWriter(logPath),true);
			ServerSocket serverSocket = new ServerSocket(port);
			while (true) {
				Socket socket = serverSocket.accept();
				Client client = new Client(socket);
				clients.add(client);
				new Thread(client).start();
			}
		}
		catch (IOException ex){
			ex.printStackTrace(System.err);
		}
		
	}
	
	private void broadcast(String read){
		Iterator it = clients.iterator();
		while (it.hasNext()) {
			Client client = (Client)it.next();			
			client.write(read);
		}
	}
		
	
	class Client
	implements Runnable{
		
		String name = null;
		Socket socket = null;
		PrintWriter socketOut = null;
		
		public Client(Socket socket) {
			this.socket = socket;			
		}
		
		public void setName(String name) {
			logger.println("User: "+name+" has just logged in.");
			this.name = name;
		}
		
			
		private void processInput(String read) {
		if (read.startsWith("USER")) {
			// authenticates
			setName(read.substring(read.indexOf(":")+1));
			processInput("LIST");
		}
		else if (read.startsWith("MESG")) {
			// broadcast
			broadcast("MESG:"+name+":"+read.substring(read.indexOf(":")+1));
		}
		
		else if (read.equals("LIST")) {
			StringBuffer buf = new StringBuffer();
			Iterator it = clients.iterator();
			while (it.hasNext()) {
				Client curClient = (Client)it.next();
				buf.append(curClient.name+",");
			}
			broadcast("LIST:"+buf.toString());
		}
	}
		
		
		public void run(){
			try {
				BufferedReader input = new BufferedReader(new InputStreamReader((socket.getInputStream())));
				socketOut = new PrintWriter(socket.getOutputStream(),true);
				String read=null;
				while ((read=input.readLine())!=null){			
					if (read.startsWith("EXIT")) {
						throw new SocketException();
					}
					else{
						processInput(read);
					}				
				}
			}
			catch (SocketException ex) {
				//System.out.println("List size: "+clients.size());
				clients.remove(clients.indexOf(this));
				processInput("LIST");
				logger.println("Socket closed. User list is now: "+clients.size());
				
			}
			catch (IOException ex){
				ex.printStackTrace(System.err);
			}
		}
		
		public void write(String read) {
			try {
				logger.println("Broadcasting: "+read);
				socketOut.println(read);			
		    }
			catch (Exception ex) {
				ex.printStackTrace(System.err);
			}			
		}
		
	}
	
	public static void main(String args[]){
		Server server = new Server(2004);		
	}
}